<?php

namespace App\Jobs;

use App\Store\Models\Basic\GoodsCategory;
use App\Store\Models\Goods\GoodsReplenish;
use App\Store\Models\Goods\GoodsReplenishInfolist;
use App\Store\Models\Goods\GoodsStockin;
use App\Store\Models\Goods\GoodsStockinInfolist;
use App\Store\Models\Goods\GoodsStockList;
use App\Store\Services\Goods\Goods;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Mockery\Expectation;
use PHPUnit\Event\Code\Throwable;
use function Laravel\Prompts\select;

class ReplenishAuditJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;


    /**
     * 补货审核
     */
    const QUEUE_JOB = 'replenish-audit-job';

    public $tries = 3;

    public $initdata = [];

    public $accountinfo = [];


    public function __construct($data, $accountinfo)
    {
        $this->initdata = $data;
        $this->accountinfo = $accountinfo;
        $this->onQueue(self::QUEUE_JOB);

    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {

        set_time_limit(0);
        ini_set('memory_limit', -1);

        $data = $this->initdata;
        $cp_id = $this->accountinfo['cp_id'] ?? 0;

        Log::info('补货审核数据', $data);
        Log::info('账号信息', $this->accountinfo);
        if (empty($data)) {
            Log::info('暂无数据');
        }

        $category = GoodsCategory::query()
            ->where(['cp_id' => $cp_id, 'is_del' => 1])
            ->get()
            ->pluck(null, 'id')
            ->toArray();

        DB::beginTransaction();
        try {
            foreach ($data as $info) {
                $id = $info['id'];

                $stock = GoodsStockList::query()
                    ->where(['cp_id' => $cp_id])
                    ->where('store_id', $info['store_id'])
                    ->where('goods_sn_code', $info['goods_sn_code'])
                    ->where('is_del', 1)
                    ->first();
                $stock = empty($stock) ? [] : $stock->toArray();

                if (empty($stock)) {

                    Log::info('商品条码' . $info['goods_sn_code'] ?? '' . '商品不存在');
                } else {
                    if ($info['count_new'] < 0 && ($stock['count'] + $info['count_new'] < 0)) {
                        Log::info('商品条码' . $info['goods_sn_code'] ?? '' . '商品补货后，库存不能小于0');
                    } else {
                        $cate = $category[$stock['goods_category_id']] ?? [];
                        if (empty($cate)) {
                            Log::info('商品条码' . $info['goods_sn_code'] ?? '' . '类别不存在不能审核');
                        } else {
                            // 更新明细
                            GoodsReplenishInfolist::query()
                                ->where(['id' => $id, 'cp_id' => $cp_id])
                                ->update(['audit_status' => 2, 'audit_success_count' => abs($info['count_new']), 'audit_at' => time()]);

                            // 明细审核状态
                            $audit_status_count = GoodsReplenishInfolist::query()
                                ->where(['p_id' => $info['p_id'], 'cp_id' => $cp_id, 'audit_status' => 1])
                                ->count();

                            if ($audit_status_count > 0) {
                                $audit_status = 2;
                            } else {
                                $audit_status = 3;
                            }

                            $count = $info['count_new'] ?? 0;
                            // 补货单审核成功数
                            GoodsReplenish::query()
                                ->where(['id' => $info['p_id'], 'cp_id' => $cp_id])
                                ->when($count > 0, function ($query) use ($count, $info, $audit_status) {
                                    $query->increment('audit_success_count', abs($info['count_new']), ['audit_status' => $audit_status]);
                                })
                                ->when($count <= 0, function ($query) use ($count, $info, $audit_status) {
                                    $query->decrement('audit_success_count', abs($info['count_new']), ['audit_status' => $audit_status]);
                                });
                            if ($count > 0) {
                                $log_type = 2;
                                $count = $stock['count'] + $info['count_new'];
                                $total_piece_weight = $stock['total_piece_weight'] + $info['total_piece_weight_new'];
                                $total_netglod_weight = $stock['total_netglod_weight'] + $info['total_netglod_weight_new'];
                            } else {
                                $log_type = 3;
                                $count = $stock['count'] - abs($info['count_new']);
                                $total_piece_weight = $stock['total_piece_weight'] - $info['total_piece_weight_new'];
                                $total_netglod_weight = $stock['total_netglod_weight'] - $info['total_netglod_weight_new'];

                            }

                            $updateStock = [];
                            $updateStock['count'] = $count;
                            $updateStock['total_piece_weight'] = $total_piece_weight;
                            $updateStock['total_netglod_weight'] = $total_netglod_weight;
                            $stock['repllennish_costglod_price'] = $info['repllennish_costglod_price'] ?? 0;

                            if ($log_type == 3) {
                                list($deduct_total_cost_fee, $remaining_cost_fee) = (new Goods())->deductTotalCost($stock, $info);
                                $updateStock['total_cost_fee'] = $remaining_cost_fee;
                            } else {
                                list($avg_costglod_price, $piececost_fee, $total_cost_fee) = (new Goods())->avgGoodsTotalCost($stock, $info, $cate['is_gram']);
                                $updateStock['costglod_price'] = $avg_costglod_price;
                                $updateStock['piececost_fee'] = $piececost_fee;
                                $updateStock['total_cost_fee'] = $total_cost_fee;
                            }

                            // 此处需要覆盖成本金价
                            $info['costglod_price'] = $info['repllennish_costglod_price'] ?? 0;
                            $info['costgram_fee'] = 0;
                            $info['costpiece_fee'] = 0;

                            Log::info('补货批量更新数据', $updateStock);
                            // 库存添加数量、总金重、总件重
                            GoodsStockList::where(['cp_id' => $cp_id, 'store_id' => $stock['store_id'], 'goods_sn_code' => $info['goods_sn_code'], 'is_del' => 1])->update($updateStock);

                            (new Goods())->addGoodLogs($this->accountinfo, 0, $info['store_id'], $info, $info['count_new'], $log_type, $info['order_sncode']);
                        }

                    }
                }
            }

            DB::commit();
        } catch (\Exception $e) {
            Log::info('商品补货审核失败' . $e->getLine() . $e->getMessage());
            $this->handleFailure($e);
            DB::rollBack();

        }
    }


    protected function handleFailure(\Throwable $e)
    {
        // 参数错误立即失败，不重试
        if ($e instanceof \InvalidArgumentException) {
            $this->failed($e);
            return;
        }

        // 可重试错误：达到最大尝试次数后标记失败
        if ($e instanceof \RuntimeException) {
            if ($this->attempts() >= $this->tries) {
                $this->failed($e);
            } else {
                throw $e;
            }
        }
    }

    public function failed(\Throwable $exception)
    {
        Log::info($exception->getMessage());
    }
}
